<template>
  <div class="inline-edit" @click.stop="handleClick" ref="wrapper">
    <input v-model="innerValue" v-if="isEditing" ref="inputRef" :class="{ 'input-error': !validateCheck }"
      placeholder="文本不能为空" />
    <slot v-else :text="innerValue"><span>{{ innerValue }}</span></slot>
  </div>
</template>
  <script setup lang="ts" name="InputEdit">
  import { type PropType, ref, watch, computed, nextTick } from 'vue'
  import useKeyPress from '@/hooks/useKeyPress'
  import useClickOutSide from '@/hooks/useClickOutSide'
  // 定义父组件传过来的值
  const props = defineProps({
    value: {
      type: String,
      required: true
    }
  });


  const innerValue = ref(props.value)
  const wrapper = ref<null | HTMLElement>(null)
  const inputRef = ref<null | HTMLInputElement>(null)
  const isOutSide = useClickOutSide(wrapper)
  const error = ref(false)
  const isEditing = ref(false)
  let cachedOldValue = ''
  const validateCheck = computed(() => {
    return innerValue.value.trim() !== ''
  })
  const emit = defineEmits(['change', 'clicked']);


  const handleClick = () => {
    isEditing.value = true
  }
  watch(isOutSide, (newValue)=>{
    if (!validateCheck.value) {
      return
    }
    if(newValue && isEditing.value) {
      isEditing.value = false
      emit('change', innerValue.value)
    }
    isOutSide.value = false //初始化isOutSide的值，防止因为click.stop带来的BUG
  })
  watch(isEditing, async(isEditing)=>{
    if (isEditing) {
      cachedOldValue = innerValue.value
      await nextTick()
      if (inputRef.value) {
        inputRef.value.focus()
      }
    }
  })
  useKeyPress('Enter', ()=>{
    if(isEditing.value) {
      isEditing.value = false
      emit('change', innerValue.value)
    }
  })
  useKeyPress('Escape', () => {
    if (isEditing.value) {
      isEditing.value = false
      innerValue.value = cachedOldValue
    }
  })

  </script>
  <style>
    .inline-edit {
        cursor: pointer;
        line-height: 32px;
        span {
          color: #eee;
        }
        input {
          padding: 0 5px;
        }
    }
    .input-error {
        border: 1px solid #f5222d;
    }
    .input-error:focus {
        border-color:  #f5222d;
    }
    .input-error::placeholder {
        color: #f5222d;
    }
  </style>